1 module hunt.cache.memcached;
2 
3 import hunt.cache.cache;
4 import hunt.cache.store;
5 import hunt.cache.nullable;
6 
7 version(SUPPORT_MEMCACHED):
8 
9 import memcache.memcache;
10 
11 class MemcachedCache
12 {
13 
14 	Nullable!V get(V)(string key)
15 	{
16 			synchronized(this){
17 				return get_inter!V(key);
18 			}
19 	}
20 
21 	Nullable!V[string] 		getall(V)(string[] keys)
22 	{
23 			//Memcache's bug not implement mget.
24 			//so it's not atomic operation, and transfer .keys.length. times througth network
25 			synchronized(this){
26 				Nullable!V[string] mapv;
27 				if(keys.length == 0)
28 					return mapv;
29 
30 				foreach(k ; keys){
31 					mapv[k] = get_inter!V(k);
32 				}
33 
34 				return mapv;
35 			}
36 
37 	}
38 	bool					containsKey(string key)
39 	{
40 			//Memcache's bug not implement exist , use get inside of.
41 			synchronized(this){
42 				return _cache.get!string(key).length > 0;
43 			}
44 	}
45 
46 
47 	void 					put(V)(string key ,  V v , uint expired)
48 	{
49 			synchronized(this){
50 				put_inter!V(key , v , expired);
51 			}
52 	}
53 	
54 	 
55 	bool					putifAbsent(V)(string key , const V v)
56 	{
57 			synchronized(this){
58 
59 				if(containsKey(key))
60 					return false;
61 
62 				put_inter!V(key , v , 0);
63 				return true;
64 				//return _cache.replace(key , cast(string)SerializeToByte!V(v));
65 			}
66 	}
67 	
68 	// because memcached api no mset api , so is cost much time to put many.
69 	void					putAll(V)( V[string] maps , uint expired)
70 	{
71 			synchronized(this){
72 
73 				foreach(k , v ; maps)
74 				{
75 					put_inter!V(k , v , expired);
76 				}
77 			}
78 
79 	}
80 	
81 	bool					remove(string key){
82 			synchronized(this){
83 				return remove_inter(key);
84 			}
85 	}
86 
87 	// because memcached api no mdel api , so is cost much time to remove many.
88 	void					removeAll(string[] keys)
89 	{
90 			synchronized(this){
91 				foreach(k  ; keys){
92 					remove_inter(k);
93 				}
94 			}
95 
96 	}
97 	void 					clear(){
98 			synchronized(this){
99 				_cache.flush();
100 			}
101 	}
102 	
103 
104 	
105 	this(string args )
106 	{
107 		if(args == null)
108 			args = "--SERVER=127.0.0.1:11211";
109 		_cache = new Memcache(args);
110 	}
111 	
112 
113 protected:
114 	Memcache _cache;
115 
116 
117 	Nullable!V				get_inter(V)(string key)
118 	{
119 		string data = _cache.get(key);
120 		return DeserializeToObject!V(cast(byte[])data);
121 	}
122 
123 	void 					put_inter(V)(string key ,  V v , uint expired)
124 	{
125 		 _cache.set(key , cast(string)SerializeToByte(v) , cast(int)expired);
126 	}
127 
128 	bool					remove_inter(string key)
129 	{
130 		return _cache.del(key);
131 	}
132 	
133 	
134 }